// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ExtendedBinding.cs" company="Concept Architecture">
//   (c) 2010 Muhammad Umer Farooq
// </copyright>
// <summary>
//   Defines the ExtendedBinding type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hisaab.Windows.Common
{
    using System.Windows;
    using System.Windows.Data;

    /// <summary>
    /// Defines the <seealso cref="ExtendedBinding"/> type.
    /// </summary>
    public class ExtendedBinding : FrameworkElement
    {
        #region Source DP

        /// <summary>
        /// We don't know what will be the Source/target type so we keep 'object'.
        /// </summary>
        public static readonly DependencyProperty TargetProperty = DependencyProperty.Register(
            "Target",
            typeof(object),
            typeof(ExtendedBinding),
            new FrameworkPropertyMetadata { BindsTwoWayByDefault = true, DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged, });

        /// <summary>
        /// We don't know what will be the Source/target type so we keep 'object'.
        /// </summary>
        public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(
            "Source",
            typeof(object),
            typeof(ExtendedBinding),
            new FrameworkPropertyMetadata { BindsTwoWayByDefault = true, DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged, });

        /// <summary>
        /// Gets or sets the source.
        /// </summary>
        /// <value>
        /// The source.
        /// </value>
        public object Source
        {
            get { return GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); }
        }

        #endregion Source DP

        #region Target DP

        /// <summary>
        /// Gets or sets the target.
        /// </summary>
        /// <value>
        /// The target.
        /// </value>
        public object Target
        {
            get { return GetValue(TargetProperty); }
            set { SetValue(TargetProperty, value); }
        }

        #endregion Target DP

        /// <summary>
        /// Invoked whenever the effective value of any dependency property on this <see cref="T:System.Windows.FrameworkElement"/> has been updated. The specific dependency property that changed is reported in the arguments parameter. Overrides <see cref="M:System.Windows.DependencyObject.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs)"/>.
        /// </summary>
        /// <param name="e">The event data that describes the property that changed, as well as old and new values.</param>
        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
            if (e.Property.Name == SourceProperty.Name)
            {
                if (!ReferenceEquals(Source, Target))
                {
                    Target = Source;
                }
            }
            else if (e.Property.Name == TargetProperty.Name)
            {
                if (!ReferenceEquals(Source, Target))
                {
                    Source = Target;
                }
            }
        }
    }
}